package com.imooc.bilibili.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.imooc.bilibili.dao.BarrageInfoDao;
import com.imooc.bilibili.entity.BarrageInfo;
import com.imooc.bilibili.service.BarrageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("barrageService")
public class BarrageServiceImpl implements BarrageService {

    @Autowired
    private BarrageInfoDao barrageInfoDao;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String BARRAGE_KEY = "barrage-video-";

    @Override
    public void insertBarrageInfoService(BarrageInfo barrageInfo) {
        barrageInfoDao.insert(barrageInfo);
    }

    @Async
    @Override
    public void asyncinsertBarrageInfoService(BarrageInfo barrageInfo) {
        barrageInfoDao.insert(barrageInfo);
    }

    @Override
    public void insertBarrageInfoServiceToRedis(BarrageInfo barrageInfo) {
        //创建key
        String barrage_key = "barrage-video-" + barrageInfo.getVideoId();
        //获取value数据
        String barrage_value = redisTemplate.opsForValue().get(barrage_key);
        List<BarrageInfo> barrageInfos = new ArrayList<>();
        if (StringUtils.isNotBlank(barrage_value)) {
            barrageInfos = JSONArray.parseArray(barrage_value, BarrageInfo.class);
        }
        barrageInfos.add(barrageInfo);
        redisTemplate.opsForValue().set(barrage_key, JSONObject.toJSONString(barrage_value));
    }

    /**
     * 数据查询优先查询Redis
     * 如果Redis中没有，继续查询数据库
     *
     * @param videoId
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<BarrageInfo> getBarrageInfoService(Long videoId, String startTime, String endTime) throws ParseException {
        String barrage_key = BARRAGE_KEY + videoId;
        String value = redisTemplate.opsForValue().get(barrage_key);
        List<BarrageInfo> barrageInfos = null;
        if (StringUtils.isNotBlank(value) && StringUtils.isNotBlank(endTime)) {
            barrageInfos = JSONArray.parseArray(value, BarrageInfo.class);
            if (StringUtils.isNotBlank(startTime)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date start = sdf.parse(startTime);
                Date end = sdf.parse(endTime);
                List<BarrageInfo> childList = new ArrayList<>();

                Iterator<BarrageInfo> iterator = barrageInfos.iterator();
                while (iterator.hasNext()) {
                    BarrageInfo next = iterator.next();
                    Date createTime = next.getCreateTime();
                    if (createTime.after(start) && createTime.before(end)) {
                        childList.add(next);
                    }
                }
                barrageInfos = childList;
            }
        } else {
            barrageInfos = barrageInfoDao.getBarrageInfoDao(videoId, startTime, endTime);
            //数据存储到Redis中进行缓存
            redisTemplate.opsForValue().set(barrage_key,JSONObject.toJSONString(barrageInfos));
        }
        return barrageInfos;
    }
}
